<script setup lang="ts">
import { onMounted, ref, VNodeRef } from "vue";
import * as THREE from "three";
// 文本缓冲几何体
import { TextGeometry } from "three/addons/geometries/TextGeometry.js";
import { FontLoader } from "three/examples/jsm/loaders/FontLoader.js";
import { OrbitControls } from "three/addons/controls/OrbitControls.js"; //鼠标控件
// import exampleFont from "three/examples/fonts/helvetiker_regular.typeface.json";
import gentilis_regular from "three/examples/fonts/gentilis_regular.typeface.json";
// Microsoft YaHei_Regular.json
// import YouSheBiaoTiHei from "@assets/fonts/YouSheBiaoTiHei_Regular.json";
// import glbDemo from '@assets/images/blender-4.1-splash.glb'
// Microsoft YaHei_Regular.json
import YouSheBiaoTiHei from "@assets/fonts/YouSheBiaoTiHei_Regular.json";


import { GLTFLoader } from "three/addons/loaders/GLTFLoader.js";
import { DRACOLoader } from "three/addons/loaders/DRACOLoader.js";

const threeContainer = ref<VNodeRef>("threeContainer");

const initThree = (container: HTMLDivElement) => {
  console.log("🚀 ~ initThree ~ container:", container);

  // 创建场景
  const scene = new THREE.Scene();
  // 创建相机
  const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  );

  // 创建渲染器
  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  // const container = document.getElementById("threejs-container");
  // 将渲染器的DOM元素添加到页面指定的DOM节点（这里是id为threejs-container的div）
  container.appendChild(renderer.domElement);

  // 创建一个立方体的几何形状
  const geometry = new THREE.BoxGeometry(1, 1, 1);
  // 创建一个基础材质，颜色设置为绿色（0x00ff00）
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
  // 创建网格物体（由几何形状和材质组成）
  const cube = new THREE.Mesh(geometry, material);
  scene.add(cube);

  camera.position.z = 5;

  const animate = () => {
    requestAnimationFrame(animate);

    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    renderer.render(scene, camera);
  };

  animate();
};

// 渲染线
const initLineThree = (container: HTMLDivElement) => {
  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  const camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    500
  );
  camera.position.set(0, 0, 100);
  camera.lookAt(0, 0, 0);
  const scene = new THREE.Scene();
  // 定义一个材质，线条能使用的材质只有LineBasicMaterial或者LineDashedMaterial
  const material = new THREE.LineBasicMaterial({ color: 0x0000ff });
  // 定义好材质之后，需要一个带有一些顶点的几何体geometry
  const points = [];
  points.push(new THREE.Vector3(-10, 0, 0));
  points.push(new THREE.Vector3(0, 10, 0));
  points.push(new THREE.Vector3(10, 0, 0));
  const geometry = new THREE.BufferGeometry().setFromPoints(points);

  // 已经有了可以画两条线的点和一个材质，可以将他们组合在一起，形成一条线
  const line = new THREE.Line(geometry, material);
  // 把它添加到场景中，并调用render渲染函数
  scene.add(line);
  renderer.render(scene, camera);
  container.appendChild(renderer.domElement);
};

// 3D文字
const initTextThree = (container: HTMLDivElement) => {
  // 创建场景
  const scene = new THREE.Scene();
  // 创建相机
  const camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    500
  );
  camera.position.set(0, 0, 100);

  camera.lookAt(0, 0, 0);

  // 创建渲染器
  const renderer = new THREE.WebGLRenderer();
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.appendChild(renderer.domElement);

  //controls.update() must be called after any manual changes to the camera's transform
  // 鼠标控件
  var controls = new OrbitControls(camera, renderer.domElement);

  // 加载字体
  const loader = new FontLoader();
  const font = loader.parse(YouSheBiaoTiHei);
  // 此处直接load字体文件没有生效，后续有时间可以看看原因
  // 原因：由于3d文本字体库文件放在public文件中，在vite打包之后，只能识别到src下的静态资源？
  // loader.load(
  //   example,
  //   function (font) {
  //   }
  // );
  const geometry = new TextGeometry("中文", {
    font: font,
    size: 100,
    height: 5,
    curveSegments: 12,
    bevelEnabled: true,
    bevelThickness: 10,
    bevelSize: 2,
    bevelSegments: 5,
  });
  // 创建材质
  const material = new THREE.MeshBasicMaterial({ color: "#79bbff" });
  // 创建网格对象
  const textMesh = new THREE.Mesh(geometry, material);
  textMesh.scale.set(0.3, 0.3, 0.3);
  // 将3D文字添加到场景中
  scene.add(textMesh);

  // 渲染循环
  const animate = () => {
    // requestAnimationFrame(animate);
    // renderer.render(scene, camera);
    requestAnimationFrame(animate);
    // required if controls.enableDamping or controls.autoRotate are set to true
    controls.update();
    textMesh.rotation.x += 0.01;
    textMesh.rotation.y += 0.02;
    renderer.render(scene, camera);
  };

  animate();
};

// 导入3D模型
const init3DModelThree = (container: HTMLDivElement) => {
  // 创建场景
  const scene = new THREE.Scene();
  scene.background = new THREE.Color(0xbfe3dd);

  // 创建相机
  const camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    100
  );
  // 相机位置
  // camera.position.set(0, 0, 100);
  camera.position.set(5, 2, 0);

  camera.lookAt(0, 0, 0);

  // 创建渲染器
  const renderer = new THREE.WebGLRenderer(); 
  // renderer.setPixelRatio(window.devicePixelRatio);
  // 设置渲染画布大小
  renderer.setSize(window.innerWidth, window.innerHeight);
  // 将画布插入dom中
  container.appendChild(renderer.domElement);

  // 创建轨道控制器
  const controls = new OrbitControls(camera, renderer.domElement);
  controls.target.set(0, 0.5, 0);
  controls.update();
  // 添加阻尼效果
  controls.enableDamping = true;
                 

  const loader = new GLTFLoader();
  const dracoLoader = new DRACOLoader();
  dracoLoader.setDecoderPath(
    "../../node_modules/three/examples/jsm/libs/draco/"
  );
  loader.setDRACOLoader(dracoLoader);

  // loader.load("/src/assets/images/cube-demo.glb", function (gltf) {
  // car车模型引入
  loader.load("/src/assets/images/lambo.glb", function (gltf) {
    console.log("🚀 ~ gltf:", gltf)
  // loader.load("../../assets/images/blender-4.1-splash.glb", function (gltf) {
    console.log("blender-4.1-splash加载成功");
    const model = gltf.scene;
    //创建光源
    // 环境光
    const light = new THREE.AmbientLight(0xffffff);
    scene.add(light);
    // model.position.set(1, 1, 0);
    model.scale.set(0.1, 0.1, 0.1);
    scene.add(model);
    // 渲染循环
    const animate = () => {
      // requestAnimationFrame(animate);
      // renderer.render(scene, camera);
      requestAnimationFrame(animate);
      // required if controls.enableDamping or controls.autoRotate are set to true
      controls.update();
      // textMesh.rotation.x += 0.01;
      // textMesh.rotation.y += 0.02;
      renderer.render(scene, camera);
    };
    animate();
  });
};

onMounted(() => {
  console.log("🚀 ~ onMounted ~ containerRef.value:", threeContainer.value);
  // initThree(threeContainer.value)
  // initLineThree(threeContainer.value);
  // initTextThree(threeContainer.value);
  init3DModelThree(threeContainer.value);
});
</script>
<template>
  <div ref="threeContainer"></div>
</template>

<style lang="scss" scoped></style>
